// 目前github上星最多的富文本编辑器
import {
  $getRoot,
  $getSelection,
  $createParagraphNode,
  $createTextNode,
} from "lexical";
import { useEffect } from "react";

import { registerDragonSupport } from "@lexical/dragon";
import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin";
import { LexicalComposer } from "@lexical/react/LexicalComposer";
import { ContentEditable } from "@lexical/react/LexicalContentEditable";
import { LexicalErrorBoundary } from "@lexical/react/LexicalErrorBoundary";
import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
import { ListPlugin } from "@lexical/react/LexicalListPlugin";
import { CheckListPlugin } from "@lexical/react/LexicalCheckListPlugin";
import { TablePlugin } from "@lexical/react/LexicalTablePlugin";
import { ClearEditorPlugin } from "@lexical/react/LexicalClearEditorPlugin";
import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
import { PlainTextPlugin } from "@lexical/react/LexicalPlainTextPlugin";
import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin";
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
import { HeadingNode, QuoteNode, registerRichText } from "@lexical/rich-text";
import { TableCellNode, TableNode, TableRowNode } from "@lexical/table";
import { ListItemNode, ListNode } from "@lexical/list";
import { CodeHighlightNode, CodeNode } from "@lexical/code";
import { AutoLinkNode, LinkNode } from "@lexical/link";

import ExampleTheme from "./theme";
import ToolbarPlugin from "./plugins/ToolbarPlugin";
import TreeViewPlugin from "./plugins/TreeViewPlugin";
import { EmojiNode } from "./plugins/emoji-plugin/EmojiNode";
import { registerEmoji } from "./plugins/emoji-plugin/EmojiPlugin";
import prepopulatedRichText from "./prepopulatedRichText";

import "./styles.css";

const theme = {
  // Theme styling goes here
  // ...
};

// When the editor changes, you can get notified via the
// LexicalOnChangePlugin!
function onChange(editorState: any) {
  console.log(editorState);
  console.log(editorState.toJSON());
  console.log(JSON.stringify(editorState));
  editorState.read(() => {
    // Read the contents of the EditorState here.
    const root = $getRoot();
    const selection = $getSelection();

    console.log(root, selection);
  });
}

// Lexical React plugins are React components, which makes them
// highly composable. Furthermore, you can lazy load plugins if
// desired, so you don't pay the cost for plugins until you
// actually use them.
function MyCustomAutoFocusPlugin() {
  const [editor] = useLexicalComposerContext();

  useEffect(() => {
    // Focus the editor when the effect fires!
    editor.focus();
    registerEmoji(editor);
    registerDragonSupport(editor);
    editor.update(prepopulatedRichText, { tag: "history-merge" });
    // editor.update(() => {
    //   // Get the RootNode from the EditorState
    //   const root = $getRoot();

    //   // Get the selection from the EditorState
    //   const selection = $getSelection();

    //   // Create a new ParagraphNode
    //   const paragraphNode = $createParagraphNode();

    //   // Create a new TextNode
    //   const textNode = $createTextNode("Hello world");

    //   // Append the text node to the paragraph
    //   paragraphNode.append(textNode);

    //   // Finally, append the paragraph to the root
    //   root.append(paragraphNode);
    // });
    // editor.setEditorState(editorState);
    // registerRichText(editor, prepopulatedRichText);
    editor.registerUpdateListener(({ editorState }) => {
      console.log(editorState.toJSON());
      console.log(JSON.stringify(editorState));
    });
  }, [editor]);

  return null;
}

// Catch any errors that occur during Lexical updates and log them
// or throw them as needed. If you don't throw them, Lexical will
// try to recover gracefully without losing user data.
function onError(error: any) {
  console.error(error);
}

const placeholder = "Enter some rich text...";

const initialEditorState =
  '{"root":{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1}],"direction":null,"format":"","indent":0,"type":"root","version":1}}';

function Editor() {
  const initialConfig = {
    namespace: "MyEditor",
    nodes: [
      HeadingNode,
      ListNode,
      ListItemNode,
      QuoteNode,
      CodeNode,
      CodeHighlightNode,
      TableNode,
      TableCellNode,
      TableRowNode,
      AutoLinkNode,
      LinkNode,
      EmojiNode,
    ],
    theme: ExampleTheme,
    editorState: initialEditorState,
    onError(error: Error) {
      throw error;
    },
  };

  return (
    <LexicalComposer initialConfig={initialConfig}>
      {/* <PlainTextPlugin
        contentEditable={<ContentEditable />}
        placeholder={<div>Enter some text...</div>}
        ErrorBoundary={LexicalErrorBoundary}
      /> */}
      <div
        className="mx-auto my-5 rounded-t-xl rounded-b rounded-lg
      max-w-5xl text-black leading-5 font-normal text-left"
      >
        <ToolbarPlugin />
        <div className="relative bg-white">
          <RichTextPlugin
            contentEditable={
              <ContentEditable
                className="min-h-[150px] h-[600px] resize-none
                text-sm caret-[#444] relative outline-none px-10 py-15"
                aria-placeholder={placeholder}
                placeholder={
                  <div
                    className="text-gray-500 overflot-hidden
                  truncate absolute top-3 left-2.5 text-sm select-none 
                  inline-block pointer-events-none"
                  >
                    {placeholder}
                  </div>
                }
              />
            }
            ErrorBoundary={LexicalErrorBoundary}
          />
          <HistoryPlugin />
          <AutoFocusPlugin />
          <TreeViewPlugin />
          <ClearEditorPlugin />
          <LinkPlugin />
          <ListPlugin />
          <CheckListPlugin />
          <TablePlugin />
          <OnChangePlugin onChange={onChange} />
          <MyCustomAutoFocusPlugin />
        </div>
      </div>
    </LexicalComposer>
  );
}

export default Editor;
